#include "stdafx.h"

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>

const double C_SPATIAL_RADIUS = 10;
const double C_COLOR_RADIUS = 8;
const int C_MAX_LEVEL = 2;
const int C_THRESH = 50;

CvMemStorage* 	cv_storage = NULL;
IplImage *in_img = NULL;

void contourThresh(){

	IplImage *out_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			3
		);
		
		//cvPyrMeanShiftFiltering( in_img, out_img, 20, 40, 2);

		IplImage *grayscale_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			1
		);

		cvCvtColor(in_img,grayscale_img,CV_BGR2GRAY);
		
		//find contours with threshold
		cvThreshold( grayscale_img, grayscale_img, C_THRESH, 255, CV_THRESH_BINARY );

		CvSeq* contours = 0;

		cvFindContours(grayscale_img, cv_storage, &contours );
		
		std::cout << contours->total << std::endl;

		cvZero( grayscale_img );
		if( contours ){
			cvDrawContours(
				grayscale_img,
				contours,
				cvScalarAll(255),
				cvScalarAll(255),
				100 );
		}
		////

		// Display the output image.
        cvNamedWindow("outImage:", CV_WINDOW_AUTOSIZE);
        cvShowImage("outImage:", grayscale_img);

        // Wait for the user to press a key in the GUI window.
        cvWaitKey(0);

        // Free the resources.
        cvDestroyWindow("inImage:");
        cvReleaseImage(&in_img);
		cvDestroyWindow("outImage:");
        cvReleaseImage(&out_img);
		cvReleaseImage(&grayscale_img);

}

void contourThreshCanny(){

	IplImage *out_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			3
		);
		
		//cvPyrMeanShiftFiltering( in_img, out_img, 20, 40, 2);

		IplImage *grayscale_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			1
		);

		cvCvtColor(in_img,grayscale_img,CV_BGR2GRAY);

		IplImage *canny_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			1
		);
		
		//find contours with threshold
		cvThreshold( grayscale_img, grayscale_img, C_THRESH, 255, CV_THRESH_BINARY );

		CvSeq* contours = 0;

		cvCanny(grayscale_img,canny_img,10,50,3);

		cvFindContours(canny_img, cv_storage, &contours );
		
		std::cout << contours->total << std::endl;

		cvZero( grayscale_img );
		if( contours ){
			cvDrawContours(
				grayscale_img,
				contours,
				cvScalarAll(255),
				cvScalarAll(255),
				100 );
		}
		////

		// Display the output image.
        cvNamedWindow("outImage:", CV_WINDOW_AUTOSIZE);
        cvShowImage("outImage:", grayscale_img);

        // Wait for the user to press a key in the GUI window.
        cvWaitKey(0);

        // Free the resources.
        cvDestroyWindow("inImage:");
        cvReleaseImage(&in_img);
		cvDestroyWindow("outImage:");
        cvReleaseImage(&out_img);
		cvReleaseImage(&grayscale_img);
		cvReleaseImage(&canny_img);
}

void contourCanny(){

	IplImage *out_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			3
		);
		
		//cvPyrMeanShiftFiltering( in_img, out_img, 20, 40, 2);

		IplImage *grayscale_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			1
		);

		cvCvtColor(in_img,grayscale_img,CV_BGR2GRAY);

		IplImage *canny_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			1
		);
		
		//find contours with threshold
		//cvThreshold( grayscale_img, grayscale_img, C_THRESH, 255, CV_THRESH_BINARY );

		CvSeq* contours = 0;

		cvCanny(grayscale_img,canny_img,10,50,3);

		

		cvFindContours(canny_img, cv_storage, &contours );
		
		std::cout << contours->total << std::endl;

		cvZero( grayscale_img );
		if( contours ){
			cvDrawContours(
				grayscale_img,
				contours,
				cvScalarAll(255),
				cvScalarAll(255),
				100 );
		}
		////

		// Display the output image.
        cvNamedWindow("outImage:", CV_WINDOW_AUTOSIZE);
        cvShowImage("outImage:", grayscale_img);

        // Wait for the user to press a key in the GUI window.
        cvWaitKey(0);

        // Free the resources.
        cvDestroyWindow("inImage:");
        cvReleaseImage(&in_img);
		cvDestroyWindow("outImage:");
        cvReleaseImage(&out_img);
		cvReleaseImage(&grayscale_img);
		cvReleaseImage(&canny_img);

}

void pre_process(){

	IplImage *out_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			3
	);

	cvSmooth(in_img,out_img,CV_BLUR,10,10);

	////

	// Display the output image.
		
	cvNamedWindow("outImage:", CV_WINDOW_AUTOSIZE);    	
	cvShowImage("outImage:", out_img);

   // Wait for the user to press a key in the GUI window.
	cvWaitKey(0);

   // Free the resources.
	cvDestroyWindow("inImage:");
	cvReleaseImage(&in_img);
	cvDestroyWindow("outImage:");
	cvReleaseImage(&out_img);
}

int _tmain(int argc, _TCHAR* argv[])
{		
		double spatial_radius = C_SPATIAL_RADIUS;
		double color_radius = C_COLOR_RADIUS;
		int max_level = C_MAX_LEVEL;

		if(argc > 0)
			spatial_radius =  *argv[0];
		if(argc > 1)
			color_radius = *argv[1];
		if(argc > 2)
			max_level = *argv[2];

		if( cv_storage == NULL ){
			cv_storage = cvCreateMemStorage(0);
		}
		

		// Open the file.
        in_img = cvLoadImage("Machovka_orange_car.png");
        if (!in_img) {
                printf("Error: Couldn't open the image file.\n");
                return 1;
        }

		/*IplImage *out_img = cvCreateImage (
			cvGetSize(in_img),
			IPL_DEPTH_8U,
			3
		);

		cvPyrMeanShiftFiltering( in_img, out_img, 20, 40, 2);*/

        // Display the input image.
        cvNamedWindow("inImage:", CV_WINDOW_AUTOSIZE);
        cvShowImage("inImage:", in_img);

		// Display the output image.
        /*cvNamedWindow("outImage:", CV_WINDOW_AUTOSIZE);
        cvShowImage("outImage:", out_img);

		// Wait for the user to press a key in the GUI window.
        cvWaitKey(0);

		cvDestroyWindow("inImage:");
        cvReleaseImage(&in_img);
		cvDestroyWindow("outImage:");
        cvReleaseImage(&out_img);*/

		//contourThresh();
		//contourCanny();
		//contourThreshCanny();
		pre_process();
        
        return 0;
}

